
<template>
    <div class="container">
        <!-- <MjpgVideo :cam1="net_cam" v-if="who"></MjpgVideo>
        <MjpgVideo :cam1="!net_cam"v-else></MjpgVideo> -->
        <iframe :src="String('http://'+serve_addr+':8889/abc')" frameborder="1" width="1020" height="594" v-if="advv"></iframe>
        <iframe :src="String('http://'+serve_addr+':8889/net_cam')" frameborder="1" width="1020" height="594" v-if="!advv && who"></iframe>
        <iframe :src="String('http://'+serve_addr+':8889/usb_video')" frameborder="1" width="1020" height="594" v-if="!advv && !who"></iframe>
        <HeadBar class="head" :qq="Number(cell_qq)" :msg="info_msg" :wendu="water_temp"></HeadBar>
        <SideBar class="side" :cam1="who" :deep="water_deep" :deng="deng"></SideBar>
        <JoyBtn ref="joy_btn" @btnC="auto_fit_fullscreen" class="head2"></JoyBtn>
        <D3Model class="buttom1" :rotate_x="Number(rov_dir.x)" :rotate_y="ro_z" :rotate_z="Number(rov_dir.y)"></D3Model>
    </div>
    <!-- <br><button @click="switch_cam">切换视频    网络像头:{{ net_cam }}</button> -->
    
</template> 

<script setup>
    import MjpgVideo from '../components/MjpgVideo.vue';
   
    import HeadBar from '../components/HeadBar.vue';
    import SideBar from '../components/SideBar.vue';
    import D3Model from '../components/D3Model.vue'
    import {ref,inject, reactive,computed,onMounted, provide,watch,nextTick} from 'vue';
    import { SerialPort } from 'tauri-plugin-serialplugin';
    //import { Command } from '@tauri-apps/plugin-shell';
    import JoyBtn from '../components/JoyBtn.vue'

    const ro_z = ref(0)
    const info_msg = ref('rov连接中...')


    //=========================ws连接中转服务到单片机串口4协议命令包=================
    const serve_addr = inject('serve_addr')
    const map_addr   = inject('map_app')
    const cell_qq = ref(99)
    const u4url = computed(()=>{
        return `ws://${serve_addr.value}:10088/ins_data`
    })
    const cell_surl = computed(()=>{
        return `ws://${serve_addr.value}:10088/cell_status`
    })
    const angle=reactive({
        x: 0.0,
        y: 0.0,
        z: 0.0
    })

    const offset_angle= reactive({
        x:0.0,
        y:0.0,
        z:0.0
    })
    const rov_dir = computed(()=>{
        let orig_x = angle.x - offset_angle.x
        if(orig_x > 300) orig_x-=360.0
        else if(orig_x < -300) orig_x +=360

        let zz = angle.z - offset_angle.z
        if(zz < -300) zz+=360
        else if(zz > 300) zz -=360

        let yy = (angle.y - offset_angle.y).toFixed(3)
        return {
            x :  orig_x.toFixed(3),  //(angle.x - offset_angle.x).toFixed(3),
            y :  yy,  // route_param.match('new22') ? -yy : yy,
            z : zz.toFixed(3)
        }
    })
    const water_deep = ref(0)
    const water_temp = ref(9.9)
    const deng       = ref(false)
    provide('led_sta',deng)
    
    import { Window } from '@tauri-apps/api/window';
    import { invoke } from '@tauri-apps/api/core';

    const appWindow = new Window('main');
    function auto_fit_fullscreen(){
        const ele = document.getElementsByTagName('iframe')[0]
        ele.width = window.innerWidth -4 
        ele.height = window.innerHeight -8
    }
    let map_app_conn = null 
    let last_gps_tim = null 
    onMounted(()=>{
        connect_uart4_proxy()
        connect_cell_monitor()
        appWindow.toggleMaximize()
        setTimeout(() => {
            auto_fit_fullscreen()
        }, 1500);
        map_app_conn = new WebSocket('ws://'+ map_addr.value +':12000')
        map_app_conn.onmessage = async (evt)=>{
            await handle_GPS(evt)
        }
    })
    const g_ws4ser = reactive({
        conn: null
    })
    provide('g_ws4ser',g_ws4ser)   //提供出去这个ws连接对象

    function connect_uart4_proxy(){
        const conn = new WebSocket(u4url.value)
        conn.onmessage = (evt)=>{
                process_uart4_data(evt)
        }
        conn.onopen = ()=>{
            g_ws4ser.conn = conn
            info_msg.value = 'rov已连接'
        }
        conn.onerror = ()=>{
            info_msg.value = 'rov连接断开'
        }
    }
    function process_uart4_data(evt){
        //console.log("通过ws收到串口4数据",evt.data)
        const reader = new FileReader()
        reader.onload = (e) => {
            const res = reader.result
            process_msg(new Uint8Array(res))
        }
        reader.readAsArrayBuffer(evt.data)
    }
    function process_msg(msg){
        const dataLen = msg[3]
        if(msg.byteLength - dataLen != 5){
            return //消息被错误的截断，难以避免，直接丢弃不要
        }
        const msgCrc = msg[msg.byteLength-1]
        let chkCrc =0;
        for(let i=0;i<msg.byteLength-1;i++){
            chkCrc +=msg[i]
        }
        chkCrc &= 0xff
        if(msgCrc != chkCrc){
            console.log("消息完整性校验失败!!",chkCrc,msgCrc)
            return
        }

        //console.log("先打印出来看看",msg)
        if(msg[2]==3){  //消息类型3 内容为传感器原始数据
            const data = new Int16Array(msg.buffer,4,3)
            angle.x = data[0]/32768*180;
            angle.y = data[1]/32768*180;
            angle.z = data[2]/32768*180;
            return
        }

        if(msg[2]==4){ //消息类型4 内容为安装误差角度
            const data = new DataView(msg.buffer,4,12)
            offset_angle.x = data.getFloat32(0,true)  // 参数true表示小端字节序
            offset_angle.y = data.getFloat32(4,true)
            offset_angle.z = data.getFloat32(8,true)
            return
        }

        if(msg[2]==5){ //消息类型5 内容为深度
            const data = new DataView(msg.buffer,4,11)
            water_deep.value = data.getInt32(0,true)
            water_temp.value = data.getInt16(4,true)/100.0
            // sensor.ms5 = data.getInt16(4,true)
            // sensor.jy9 = data.getInt16(6,true)

            // key_task.stable = data.getInt8(8)
            // key_task.mov    = data.getInt8(9)
            // key_task.deep   = data.getInt8(10)
            //console.log("计算得到水温度",water_temp.value)
            return
        }

        if(msg[2]==0x20){  //消息类型是4个深度电机的PWM值
            // const data = new DataView(msg.buffer,4,8)
            // pwms.m5 = data.getInt16(0,true)
            // pwms.m6 = data.getInt16(2,true)
            // pwms.m7 = data.getInt16(4,true)
            // pwms.m8 = data.getInt16(6,true)
            return
        }

        if(msg[2]==0x21){ //消息类型是4个运动电机的PWM值
            // const data = new Int16Array(msg.buffer,4,4)
            // mov_pwms.m1 = data[0]
            // mov_pwms.m2 = data[1]
            // mov_pwms.m3 = data[2]
            // mov_pwms.m4 = data[3]
        }

        if(msg[2]== 0xa2){ //GPS数据
            const gps_data = msg.slice(4,dataLen+4)
            const now = new Date()
            if(last_gps_tim && (now-last_gps_tim > 49*100) && 
                map_app_conn && map_app_conn.readyState ==1){
                    map_app_conn.send(gps_data)
                    last_gps_tim = now 
            }else if(null == last_gps_tim && map_app_conn && map_app_conn.readyState ==1){
                map_app_conn.send(gps_data)
                last_gps_tim = now 
            }

        }
    }

    function connect_cell_monitor(){
        const conn = new WebSocket(cell_surl.value)
        conn.onmessage=(evt)=>{
            //console.log('电池监测消息',evt.data)
            const dd = JSON.parse(evt.data)
            //console.log(dd)
            if(dd.remainQ != undefined && dd.totalQ != undefined){
                cell_qq.value = Number( ( (dd.remainQ / dd.totalQ)*100).toFixed(1) ) 
            }
        }

    }

    async function handle_GPS(evt){
        console.log("地图程序解析出来的坐标数据：",evt.data, "数据类型是",typeof(evt.data))
        const param = evt.data //JSON.stringify(evt.data)
        if(typeof(param) =='string'){
            await invoke("write_gps_data",{ss: param})
        }else{
            await invoke("write_gps_data",{ss: String(param)})
        }
    }

    //===================串口设备访问读取手柄输入=======================
    const port_name  = inject('uart_port')
    const port = new SerialPort({ 
        path: port_name.value, 
        baudRate: 115200 ,
        stopBits: 1
    });
    const joy_btn = ref()
    port.open().then(async (res)=>{
        //console.log('open串口设备', res);
        port.read().then(()=>{}) //要先读一下再调用listen函数安装监听器 就可以得到串口数据了

        port.listen(async (data) => {
            console.log('Received:', data);
            await joy_btn.value.handle_joy_input(data)
        }).then(()=>{ });
    });
    
    

    //======================切换两个摄像头=========================
    const net_cam = ref(true)
    const who = ref(true)
    const advv = ref(false)
    provide('who',who)
    provide('advv',advv)
    watch([who,advv],([who2,advv2])=>{
        if(!who2 && !advv2){
            nextTick(()=>{
                const ff = document.getElementsByTagName('iframe')[0]
                ff.style="transform:rotate(180deg)"
            })
        }
    })
    function switch_cam(evt){
        who.value = !who.value
        evt.target.style.backgroundColor =" rgb(222,98,98)"
        setTimeout(()=>{
            evt.target.style.backgroundColor=''
        },200)
    }
</script>



<style scoped>
.container{
    position: relative;
    width: 100%;
}
.head{
    position: absolute;
    top:0;
    left: 0;
}
.side{
    position: absolute;
    left: 10px;
    top:calc(35%);
}
.buttom1{
    position: absolute;
    bottom: 10px;
    right: 25%;
}
.head2{
    position: absolute;
    top: 2.5em;
    left: calc(50%);
    transform: translate(-50%,0);
}
</style>